package com.common.io.token;

/**
 * 此类为 mybatis 的占位符解释类 org.apache.ibatis.parsing.GenericTokenParser
 * 
 * @author Clinton Begin
 * 
 * 用来解释占位符里的字符串，占位符包括起始占位符和结束占位符，另外一个包含一个对占位符里的的字符串的处理器。
 * 这种占位符处理的方式比较广，另外有一种是针对有限占位符的处理方法。<a href="http://peiquan.blog.51cto.com/7518552/1580189"> tomcat 日志 pattern 设置</a>。
 */
public class GenericTokenParser {

	/** 起始占位符 */
	private final String openToken;	
	/** 结束占位符 */
	private final String closeToken;
	/** 占位符处理器 */
	private final TokenHandler handler;

	public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
		this.openToken = openToken;
		this.closeToken = closeToken;
		this.handler = handler;
	}

	public String parse(String text) {
		StringBuilder builder = new StringBuilder();
		if (text != null && text.length() > 0) {
			char[] src = text.toCharArray();
			int offset = 0;
			int start = text.indexOf(openToken, offset);
			while (start > -1) {
				if (start > 0 && src[start - 1] == '\\') {// 在某些字符串里，转义的实现
					// the variable is escaped. remove the backslash.
					builder.append(src, offset, start - offset - 1).append(openToken);
					offset = start + openToken.length();
				} else {
					int end = text.indexOf(closeToken, start);
					if (end == -1) {
						builder.append(src, offset, src.length - offset);
						offset = src.length;
					} else {
						builder.append(src, offset, start - offset);
						offset = start + openToken.length();
						String content = new String(src, offset, end - offset);
						builder.append(handler.handleToken(content));
						offset = end + closeToken.length();
					}
				}
				start = text.indexOf(openToken, offset);
			}
			if (offset < src.length) {
				builder.append(src, offset, src.length - offset);
			}
		}
		return builder.toString();
	}

}
